package com.aps.common.model.test;

import com.aps.common.model.APSProductModel;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;

/**
 * APS产品模型数据生成器
 * 用于快速生成各种测试用例和场景数据
 */
public class APSProductModelGenerator {
    
    private static final Random random = new Random();
    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    
    // 预定义的数据池
    private static final String[] PRODUCT_NAMES = {
        "汽车齿轮", "发动机零件", "刹车盘", "转向节", "减震器", "轴承", "密封圈", "弹簧", "螺栓", "螺母"
    };
    
    private static final String[] PRODUCT_CATEGORIES = {
        "齿轮", "发动机", "制动", "转向", "悬挂", "传动", "密封", "紧固件", "弹簧件", "轴承"
    };
    
    private static final String[] MATERIALS = {
        "合金钢", "不锈钢", "碳钢", "铝合金", "铜合金", "钛合金", "铸铁", "塑料", "橡胶", "陶瓷"
    };
    
    private static final String[] CUSTOMER_NAMES = {
        "大众汽车", "宝马汽车", "奔驰汽车", "奥迪汽车", "丰田汽车", "本田汽车", "福特汽车", 
        "通用汽车", "特斯拉", "比亚迪", "长城汽车", "吉利汽车", "奇瑞汽车", "长安汽车", "东风汽车"
    };
    
    private static final String[] CUSTOMER_LEVELS = {"A", "B", "C"};
    
    private static final String[] PRIORITIES = {"高", "中", "低"};
    
    private static final String[] OPERATION_NAMES = {
        "车削", "铣削", "钻孔", "磨削", "镗孔", "攻丝", "切割", "焊接", "热处理", "表面处理", 
        "装配", "质检", "包装", "清洗", "涂装"
    };
    
    private static final String[] EQUIPMENT_TYPES = {
        "CNC车床", "CNC铣床", "钻床", "磨床", "镗床", "攻丝机", "切割机", "焊接机", 
        "热处理炉", "表面处理设备", "装配线", "质检台", "包装机", "清洗机", "涂装线"
    };
    
    private static final String[] PERSONNEL_POSITIONS = {
        "操作工", "技术员", "质检员", "装配工", "维修工", "工程师", "班组长", "主管"
    };
    
    private static final String[] SKILL_LEVELS = {"初级", "中级", "高级", "专家"};
    
    private static final String[] EQUIPMENT_STATUS = {"正常", "维护中", "故障", "闲置"};
    
    private static final String[] PERSONNEL_STATUS = {"在职", "休假", "培训", "离职"};
    
    /**
     * 生成基础测试模型
     */
    public static APSProductModel generateBasicModel() {
        return generateModel(5, 4, 4, 3, false);
    }
    
    /**
     * 生成小规模测试模型
     */
    public static APSProductModel generateSmallModel() {
        return generateModel(3, 3, 3, 2, false);
    }
    
    /**
     * 生成中等规模测试模型
     */
    public static APSProductModel generateMediumModel() {
        return generateModel(10, 6, 8, 5, true);
    }
    
    /**
     * 生成大规模测试模型
     */
    public static APSProductModel generateLargeModel() {
        return generateModel(20, 10, 15, 8, true);
    }
    
    /**
     * 生成高优先级订单模型
     */
    public static APSProductModel generateHighPriorityModel() {
        APSProductModel model = generateBasicModel();
        model.getOrders().forEach(order -> order.setPriority("高"));
        return model;
    }
    
    /**
     * 生成紧急交期模型
     */
    public static APSProductModel generateUrgentDeliveryModel() {
        APSProductModel model = generateBasicModel();
        LocalDate today = LocalDate.now();
        model.getOrders().forEach(order -> {
            // 设置交期为未来1-3天
            int days = random.nextInt(3) + 1;
            order.setDeliveryDate(today.plusDays(days).format(DATE_FORMATTER));
            order.setPriority("高");
        });
        return model;
    }
    
    /**
     * 生成资源紧张模型
     */
    public static APSProductModel generateResourceConstrainedModel() {
        APSProductModel model = generateBasicModel();
        // 减少资源数量
        model.getResources().getEquipment().removeIf(eq -> random.nextBoolean());
        model.getResources().getPersonnel().removeIf(p -> random.nextBoolean());
        return model;
    }
    
    /**
     * 生成复杂工艺模型
     */
    public static APSProductModel generateComplexProcessModel() {
        APSProductModel model = generateBasicModel();
        // 增加工序数量
        int additionalOps = random.nextInt(3) + 2;
        for (int i = 0; i < additionalOps; i++) {
            model.getOperations().add(generateOperation(
                "OP" + String.format("%03d", model.getOperations().size() + 1),
                model.getOperations().size() + 1
            ));
        }
        return model;
    }
    
    /**
     * 生成自定义模型
     */
    public static APSProductModel generateModel(int orderCount, int operationCount, 
                                               int equipmentCount, int personnelCount, 
                                               boolean includeConstraints) {
        APSProductModel model = new APSProductModel();
        
        // 生成产品信息
        model.setProduct(generateProduct());
        
        // 生成订单
        List<APSProductModel.ProductionOrder> orders = new ArrayList<>();
        for (int i = 0; i < orderCount; i++) {
            orders.add(generateOrder("ORD" + String.format("%03d", i + 1)));
        }
        model.setOrders(orders);
        
        // 生成工序
        List<APSProductModel.Operation> operations = new ArrayList<>();
        for (int i = 0; i < operationCount; i++) {
            operations.add(generateOperation("OP" + String.format("%03d", i + 1), i + 1));
        }
        model.setOperations(operations);
        
        // 生成资源
        APSProductModel.Resources resources = new APSProductModel.Resources();
        
        List<APSProductModel.EquipmentResource> equipment = new ArrayList<>();
        for (int i = 0; i < equipmentCount; i++) {
            equipment.add(generateEquipment("EQ" + String.format("%03d", i + 1)));
        }
        resources.setEquipment(equipment);
        
        List<APSProductModel.PersonnelResource> personnel = new ArrayList<>();
        for (int i = 0; i < personnelCount; i++) {
            personnel.add(generatePersonnel("PER" + String.format("%03d", i + 1)));
        }
        resources.setPersonnel(personnel);
        
        model.setResources(resources);
        
        // 生成约束条件（可选）
        if (includeConstraints) {
            model.setConstraints(generateConstraints());
        }
        
        // 生成元数据
        model.setMetadata(generateMetadata());
        
        return model;
    }
    
    /**
     * 生成产品信息
     */
    private static APSProductModel.Product generateProduct() {
        APSProductModel.Product product = new APSProductModel.Product();
        product.setId("PROD-" + random.nextInt(1000));
        product.setName(getRandomElement(PRODUCT_NAMES));
        product.setCategory(getRandomElement(PRODUCT_CATEGORIES));
        product.setMaterial(getRandomElement(MATERIALS));
        product.setModel("MODEL-" + random.nextInt(100));
        product.setSpecification("标准规格");
        product.setAnnualDemand(random.nextInt(50000) + 10000);
        
        // 生成规格信息
        Map<String, Object> specifications = new HashMap<>();
        specifications.put("长度", random.nextDouble() * 100 + 10);
        specifications.put("宽度", random.nextDouble() * 50 + 5);
        specifications.put("高度", random.nextDouble() * 30 + 2);
        specifications.put("重量", random.nextDouble() * 10 + 0.5);
        product.setSpecifications(specifications);
        
        return product;
    }
    
    /**
     * 生成生产订单
     */
    private static APSProductModel.ProductionOrder generateOrder(String orderId) {
        APSProductModel.ProductionOrder order = new APSProductModel.ProductionOrder();
        order.setId(orderId);
        order.setCustomerName(getRandomElement(CUSTOMER_NAMES));
        order.setCustomerLevel(getRandomElement(CUSTOMER_LEVELS));
        order.setProductModel("MODEL-" + random.nextInt(100));
        order.setQuantity(random.nextInt(1000) + 100);
        order.setPriority(getRandomElement(PRIORITIES));
        order.setOrderAmount(random.nextDouble() * 100000 + 10000);
        order.setPriorityScore(random.nextDouble());
        
        // 生成交期（未来7-30天）
        LocalDate today = LocalDate.now();
        int days = random.nextInt(24) + 7;
        order.setDeliveryDate(today.plusDays(days).format(DATE_FORMATTER));
        
        // 计算关键比率
        order.setCriticalRatio(random.nextDouble() * 2 + 0.5);
        
        return order;
    }
    
    /**
     * 生成工序信息
     */
    private static APSProductModel.Operation generateOperation(String operationId, int sequence) {
        APSProductModel.Operation operation = new APSProductModel.Operation();
        operation.setId(operationId);
        operation.setName(getRandomElement(OPERATION_NAMES));
        operation.setSequence(sequence);
        operation.setEquipmentType(getRandomElement(EQUIPMENT_TYPES));
        operation.setStandardTime(random.nextDouble() * 60 + 10); // 10-70分钟
        operation.setSetupTime(random.nextDouble() * 30 + 5); // 5-35分钟
        operation.setPersonnelRequirement(getRandomElement(PERSONNEL_POSITIONS));
        operation.setQualityRequirement("标准质量要求");
        
        // 生成前置工序
        if (sequence > 1) {
            List<String> predecessors = new ArrayList<>();
            for (int i = 1; i < sequence; i++) {
                if (random.nextBoolean()) {
                    predecessors.add("OP" + String.format("%03d", i));
                }
            }
            operation.setPredecessorOperations(predecessors);
        }
        
        // 生成所需资源
        List<String> requiredResources = new ArrayList<>();
        requiredResources.add("EQ" + String.format("%03d", random.nextInt(4) + 1));
        operation.setRequiredResources(requiredResources);
        
        return operation;
    }
    
    /**
     * 生成设备资源
     */
    private static APSProductModel.EquipmentResource generateEquipment(String equipmentId) {
        APSProductModel.EquipmentResource equipment = new APSProductModel.EquipmentResource();
        equipment.setId(equipmentId);
        equipment.setName(getRandomElement(EQUIPMENT_TYPES));
        equipment.setType("加工设备");
        equipment.setDailyCapacity(480.0); // 8小时
        equipment.setEfficiencyFactor(random.nextDouble() * 0.2 + 0.8); // 0.8-1.0
        equipment.setStatus(getRandomElement(EQUIPMENT_STATUS));
        equipment.setMaintenanceSchedule("每周维护");
        
        // 生成能力列表
        List<String> capabilities = new ArrayList<>();
        capabilities.add("精密加工");
        capabilities.add("批量生产");
        if (random.nextBoolean()) {
            capabilities.add("自动化");
        }
        equipment.setCapabilities(capabilities);
        
        return equipment;
    }
    
    /**
     * 生成人员资源
     */
    private static APSProductModel.PersonnelResource generatePersonnel(String personnelId) {
        APSProductModel.PersonnelResource personnel = new APSProductModel.PersonnelResource();
        personnel.setId(personnelId);
        personnel.setName("员工" + random.nextInt(1000));
        personnel.setPosition(getRandomElement(PERSONNEL_POSITIONS));
        personnel.setJobType(getRandomElement(PERSONNEL_POSITIONS));
        personnel.setSkillLevel(getRandomElement(SKILL_LEVELS));
        personnel.setDailyWorkHours(8.0);
        personnel.setStatus(getRandomElement(PERSONNEL_STATUS));
        personnel.setEfficiencyFactor(random.nextDouble() * 0.3 + 0.7); // 0.7-1.0
        
        // 生成技能列表
        List<String> skills = new ArrayList<>();
        skills.add("设备操作");
        skills.add("质量控制");
        if (random.nextBoolean()) {
            skills.add("故障排除");
        }
        personnel.setSkills(skills);
        
        // 生成可操作设备
        List<String> operableEquipment = new ArrayList<>();
        operableEquipment.add("EQ" + String.format("%03d", random.nextInt(4) + 1));
        personnel.setOperableEquipment(operableEquipment);
        
        return personnel;
    }
    
    /**
     * 生成约束条件
     */
    private static APSProductModel.Constraints generateConstraints() {
        APSProductModel.Constraints constraints = new APSProductModel.Constraints();
        
        // 生成硬约束
        List<APSProductModel.HardConstraint> hardConstraints = new ArrayList<>();
        APSProductModel.HardConstraint hardConstraint = new APSProductModel.HardConstraint();
        hardConstraint.setId("HC001");
        hardConstraint.setType("时间");
        hardConstraint.setDescription("订单必须在指定时间内完成");
        hardConstraint.setPriority("高");
        
        Map<String, Object> hardParams = new HashMap<>();
        hardParams.put("maxDelayDays", 3);
        hardParams.put("penaltyCost", 1000.0);
        hardConstraint.setParameters(hardParams);
        hardConstraints.add(hardConstraint);
        constraints.setHardConstraints(hardConstraints);
        
        // 生成软约束
        List<APSProductModel.SoftConstraint> softConstraints = new ArrayList<>();
        APSProductModel.SoftConstraint softConstraint = new APSProductModel.SoftConstraint();
        softConstraint.setId("SC001");
        softConstraint.setType("成本");
        softConstraint.setDescription("总成本不能超过预算");
        softConstraint.setWeight(0.7);
        
        Map<String, Object> softParams = new HashMap<>();
        softParams.put("maxCost", 100000.0);
        softParams.put("costWeight", 0.8);
        softConstraint.setParameters(softParams);
        softConstraints.add(softConstraint);
        constraints.setSoftConstraints(softConstraints);
        
        return constraints;
    }
    
    /**
     * 生成元数据
     */
    private static Map<String, Object> generateMetadata() {
        Map<String, Object> metadata = new HashMap<>();
        metadata.put("generatedAt", LocalDate.now().toString());
        metadata.put("version", "1.0");
        metadata.put("generator", "APSProductModelGenerator");
        metadata.put("scenario", "test");
        return metadata;
    }
    
    /**
     * 从数组中随机选择元素
     */
    private static String getRandomElement(String[] array) {
        return array[random.nextInt(array.length)];
    }
    
    /**
     * 生成指定数量的随机整数
     */
    public static int randomInt(int min, int max) {
        return ThreadLocalRandom.current().nextInt(min, max + 1);
    }
    
    /**
     * 生成指定范围的随机双精度数
     */
    public static double randomDouble(double min, double max) {
        return ThreadLocalRandom.current().nextDouble(min, max);
    }
    
    /**
     * 生成随机日期
     */
    public static String randomDate(int minDays, int maxDays) {
        LocalDate today = LocalDate.now();
        int days = randomInt(minDays, maxDays);
        return today.plusDays(days).format(DATE_FORMATTER);
    }
    
    /**
     * 生成随机布尔值
     */
    public static boolean randomBoolean() {
        return random.nextBoolean();
    }
    
    /**
     * 从列表中随机选择元素
     */
    public static <T> T randomElement(List<T> list) {
        if (list == null || list.isEmpty()) {
            return null;
        }
        return list.get(random.nextInt(list.size()));
    }
}
